/*
Think about how it handles different outputs, formats, filters, custom logger implementations?
	Different outputs are handled by providing the target as parameter (CONSOLE, FILE,...). Most probably not the best solution, because every target needs its own
	implementation and also initialization which is all implemented in the Logger class.
	Another thing is that you always have to provide a lot of arguments when logging some messages (target, channel, ...).
	filtering happens via global log level

	In general i think this (try of a) solution is totally crap and absolutely not satisfying at all (for me as well), but i had to fight with a bad migraine the last two days
	which did not make it easier to work on a passable solution. Of course this shouldn't be an excuse and i'm sure that the next exercise will be a better one.


*/



#include <stdio.h>
#include <windows.h>
#include <string>

#define ENABLE_LOGGING 0

#ifdef _DEBUG
#define ENABLE_LOGGING 1
#endif

enum output {CONSOLE, LOGFILE, WHATEVER};

#if ENABLE_LOGGING == 1
	#define  LOGLEVEL = 0
	//create instance of logger
	#define CREATE_LOGGER Logger MyLogger;
	//define log function as macro
	#define LOG //...

	//some initializing for different log types should also be necessary
	#define INITIALIZE_CONSOLE //...
	#define INITIALIZE_FILE //...
	#define INITIALIZE_WHATEVER //...

#else
//define all macros as empty
#define CREATE_LOGGER
/...
#endif


using namespace std;



class Logger
{

public:
	Logger(void);
	~Logger(void);
public:
	/*
	* verbosity... log level (fatal, error, warn, info,...)
	* channel... graphics, audio, ...
	* file... file
	* line... number of line
	* logMsg... log message
	*/
	void Log(output target, int level,string channel, string file, int line, string logMsg)
	{
		//only print when global verbosity level is high enough
		if(LOGLEVEL >= level)
		{
			//format log message based on output target
			FormatLogMessage(target,level, channel, file, line, logMsg);

			switch(target)
			{
			case CONSOLE:
				LogToConsole(level, channel, file, line, logMsg);
				break;
			case LOGFILE:
				LogToFile(level, channel, file, line, logMsg);
				break;
			case WHATEVER:
				LogToWhatever(level, channel, file, line, logMsg);
				break;
			}
		}
	}

	void FormatLogMessage(output target, int level, string channel, string file, int line, string logMsg)
	{

	}
	void LogToConsole(int level, string channel, string file, int line, string logMsg)
	{
		//implement functionality here
	}
	void LogToFile(int level, string channel, string file, int line, string logMsg)
	{
		//implement functionality here
	}
	void LogToWhatever(int level, string channel, string file, int line, string logMsg)
	{
		//implement functionality here
	}

	void Initialize_FileLogger()
	{
		//prepare file for writing
	}

	void Initialize_ConsoleLogger()
	{

	}

};


void main(void)
{
	CREATE_LOGGER;
	INITIALIZE_CONSOLE;
	LOG(CONSOLE, "main",__FILE__, __LINE__, "log entry from main function");
}
